package com.googlecode.cryptoid;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.Stack;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class EditMatrix extends Activity {
	
	
	private TextView sizeText;
	private EditText nameText;
	public static boolean newMatrix;
	int size;
	boolean go = false;
	Intent intent;
	
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        size = Matrix.size;
        setView();
        
        }
	
	
	public void reloadMatrix(View button){
		size = Matrix.size;
		setView();
  
	}

    public void saveMatrix(View button){
    	save();
    }

    
    public void saveAndGo(View button){
    	intent = new Intent(this, ViewMessage.class);
    	go = true;
    	if(save()){
    		go = false;
        	startActivity(intent);
        	finish();
    	}
    }
    
    private boolean save(){
    	if (newMatrix && fileExists()){
    		overWriteDialog();
    		return false;
    	}
    	else{
    		getData();
    		if (!toMatrixList())
				Toast.makeText(this, R.string.couldntwritelist ,Toast.LENGTH_SHORT).show();
    		if (matrixToFile()){
    			newMatrix = false;
    			return true;
    		}
    		else
    			return false;
    	}
    }
    
    
	public void changeSize(View senderView) {
    	switch(senderView.getId()){
        case R.id.size_minus:
        	getData();
        	size--;
        	break;
        case R.id.size_plus:
        	getData();
        	size++;
        	break;
    	}
    	
    	if(size < 2){
    		Toast.makeText(this, R.string.smallmatrix, Toast.LENGTH_SHORT).show();
    		size++;
    	}
    	else if(size > 4){
    		Toast.makeText(this, R.string.largematrix , Toast.LENGTH_SHORT).show();
    		size--;
    	}
    	else{
    		setView();
    	}
    	
    }
    
    
    private void setView(){
        switch(size){
        case 2:
        	setContentView(R.layout.matrix2);
        	break;
        case 3:
        	setContentView(R.layout.matrix3);
        	break;
        case 4:
        	setContentView(R.layout.matrix4);
        	break;
        default:
        	Toast.makeText(this, R.string.impropersize , Toast.LENGTH_SHORT).show();
    	}
        
        String sizeString=Integer.toString(size);
        sizeText = (TextView) findViewById(R.id.size_of_matrix); 
        sizeText.setText((CharSequence) sizeString);
        
        nameText = (EditText) findViewById(R.id.matrix_name);
        nameText.setText((CharSequence) Matrix.name);
        
        fillValues();
    }
    
    
    private void fillValues(){
    	int[][] matrix = Matrix.matrix;
    	String valueString;
    	
		for(int i=0 ; i < size; i++){
			for(int j=0 ; j < size; j++){
				valueString = Integer.toString(matrix[i][j]);
				getValueField(i,j).setText((CharSequence)valueString);
			}
		}
    }
	
    private void getData(){
		for(int i=0 ; i < size; i++){
			for(int j=0 ; j < size; j++){
				Matrix.matrix[i][j] = Integer.parseInt(getValueField(i,j).getText().toString());
			}
		}
		
		Matrix.size = size;
		
		nameText = (EditText) findViewById(R.id.matrix_name);
		String nameString = nameText.getText().toString();
		
		if (!nameString.equals(Matrix.name)){
			newMatrix = true;
		}
		Matrix.name = nameString;
					
    }
    
    private EditText getValueField(int row, int column){
    	switch(row){
    	case 0:
    		switch (column){
    			case 0:
    				return (EditText) findViewById(R.id.aa);
    			case 1:
    				return (EditText) findViewById(R.id.ab);
    			case 2:
    				return (EditText) findViewById(R.id.ac);
    			case 3:
    				return (EditText) findViewById(R.id.ad);
    		}
    	case 1:
    		switch (column){
    			case 0:
    				return (EditText) findViewById(R.id.ba);
    			case 1:
    				return (EditText) findViewById(R.id.bb);
    			case 2:
    				return (EditText) findViewById(R.id.bc);
    			case 3:
    				return (EditText) findViewById(R.id.bd);
    		}
    	case 2:
    		switch (column){
    			case 0:
    				return (EditText) findViewById(R.id.ca);
    			case 1:
    				return (EditText) findViewById(R.id.cb);
    			case 2:
    				return (EditText) findViewById(R.id.cc);
    			case 3:
    				return (EditText) findViewById(R.id.cd);
    		}
    	case 3:
    		switch (column){
    			case 0:
    				return (EditText) findViewById(R.id.da);
    			case 1:
    				return (EditText) findViewById(R.id.db);
    			case 2:
    				return (EditText) findViewById(R.id.dc);
    			case 3:
    				return (EditText) findViewById(R.id.dd);
    		}
    	default:
    		return null;
    	}
    }
    
    private boolean fileExists(){
    	nameText = (EditText) findViewById(R.id.matrix_name);
    	try {
			ObjectInputStream input = new ObjectInputStream(openFileInput(nameText.getText().toString() + ".mtx"));
			input.close();
			return true;
		} catch (StreamCorruptedException e1) {
			return false;
		} catch (FileNotFoundException e1) {
			return false;
		} catch (IOException e1) {
			return false; 
		}
    }
    
    private void overWriteDialog() {
    	AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	builder.setMessage("'" + Matrix.name + getString(R.string.overwrite))
    	       .setCancelable(true)
    	       .setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
    	           public void onClick(DialogInterface dialog, int id) {
    	        	   getData();
    	        	   if (matrixToFile())
    	                	newMatrix= false;
    	        	   if (go){
    	        		   	go = false;
    	           			startActivity(intent);
    	        	   }
    	           }
    	       })
    	       .setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() {
    	           public void onClick(DialogInterface dialog, int id) {
    	                dialog.cancel();
    	           }
    	       });
    	builder.show();
    	
	}
    
    private boolean matrixToFile(){
    	if(!Matrix.initialize()){
    		Toast.makeText(this, R.string.detzero ,Toast.LENGTH_LONG).show();
    		Toast.makeText(this, R.string.couldntwrite ,Toast.LENGTH_SHORT).show();
    		return false;
    	}
    	
		try {
			ObjectOutputStream output = new ObjectOutputStream(openFileOutput(Matrix.name + ".mtx", MODE_PRIVATE));
			int [] sizeArray = {size};
			int [][] dummyArray = {sizeArray};
			int[][][] dataArray = {Matrix.matrix, dummyArray};
			output.writeObject(dataArray);
			output.close();
			Toast.makeText(this, R.string.matrixsaved ,Toast.LENGTH_SHORT).show();
			return true;
			
			} 
			catch (IOException e){
				Toast.makeText(this, R.string.couldntwrite ,Toast.LENGTH_SHORT).show();
				return false;
			}
    }
    


private boolean toMatrixList() {
	boolean inputReady = true;
	int len = 0;
	Stack<String> namesStack = new Stack<String>();

	if(!fileExists()){
		ObjectInputStream input;
		try {
			input = new ObjectInputStream(openFileInput(".mtxlist"));
			if(inputReady){
				String[] namesIn = (String[]) input.readObject();
				input.close();
			
				len = namesIn.length;
				
				for(int i = 1; i <= len; i++)
					namesStack.add(namesIn[len - i]);
				
			}
		}
		  catch (FileNotFoundException e) {
			inputReady = false;
		} catch (StreamCorruptedException e) {
			return false;
		} catch (IOException e) {
			return false;
		} catch (ClassNotFoundException e) {
			return false;
		} 
	
		String[] namesOut = new String[len+1];
		
		for(int i = 0; i < len; i ++)
			namesOut[i] = namesStack.pop();
		namesOut[len] = Matrix.name;
		
		ObjectOutputStream output;
		try {
			output = new ObjectOutputStream(openFileOutput(".mtxlist", MODE_PRIVATE));
			output.writeObject(namesOut);
			output.close();
		} catch (FileNotFoundException e) {
			return false;
		} catch (IOException e) {
			return false;
		}
		return true;
	}
	else
		return true;
}

}